package tacos.data;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
import tacos.Ingredient;
import tacos.User;

@Configuration
public class DataLoaderConfig {

    private PasswordEncoder passwordEncoder;

    @Autowired
    public DataLoaderConfig(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    /*
     * 使用JdbcTemplate时，我们在应用启动阶段会借助data.sql预加载Ingredient数据，这个过程会在数据源bean初始化的时候针对数据库来执行。
     * 同样的方式也适用于Spring Data JDBC。实际上，它适用于任何以关系型数据库作为支撑数据库的持久化机制。
     * 但是，不妨看一下另一种在启动时填充数据库的方式，这种方式会提供更多的灵活性。
     * Spring Boot提供了两个非常有用的接口，用于在应用启动的时候执行一定的逻辑，即CommandLineRunner和ApplicationRunner。
     * 这两个接口非常类似，它们都是函数式接口，都需要实现一个run()方法。
     * 当应用启动的时候，应用上下文中所有实现了CommandLineRunner或ApplicationRunner的bean都会执行其run()方法，
     * 执行时机是应用上下文和所有bean装配完毕之后、所有其他功能执行之前。这为将数据加载到数据库中提供了便利。
     * CommandLineRunner和ApplicationRunner都是函数式接口，所以在配置类中可以很容易地将其声明为bean，
     * 只需在一个返回lambda表达式的方法上使用@Bean注解。
     * */
    @Bean
    public ApplicationRunner dataLoader(IngredientRepository repo) {
        return args -> {
            repo.save(new Ingredient("FLTO", "Flour Tortilla", Ingredient.Type.WRAP));
            repo.save(new Ingredient("COTO", "Corn Tortilla", Ingredient.Type.WRAP));
            repo.save(new Ingredient("GRBF", "Ground Beef", Ingredient.Type.PROTEIN));
            repo.save(new Ingredient("CARN", "Carnitas", Ingredient.Type.PROTEIN));
            repo.save(new Ingredient("TMTO", "Diced Tomatoes", Ingredient.Type.VEGGIES));
            repo.save(new Ingredient("LETC", "Lettuce", Ingredient.Type.VEGGIES));
            repo.save(new Ingredient("CHED", "Cheddar", Ingredient.Type.CHEESE));
            repo.save(new Ingredient("JACK", "Monterrey Jack", Ingredient.Type.CHEESE));
            repo.save(new Ingredient("SLSA", "Salsa", Ingredient.Type.SAUCE));
            repo.save(new Ingredient("SRCR", "Sour Cream", Ingredient.Type.SAUCE));
        };
    }

    @Bean
    public ApplicationRunner dataLoader1(UserRepository repo) {
        return args -> {
            User user = repo.save(new User("cgs", this.passwordEncoder.encode("cgs"), "code god speed", "sjz", "sjz", "0", "060000", "0335-2020202"));
        };
    }
}
